package net.goodapp.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import net.goodapp.model.ColumnInfo;
import net.goodapp.model.TableInfo;

/**
 * PowerDesigner生成的pdm文件的阅读器
 * @author zhou.jin-qiao
 *
 */
public class PdmReader {
	private static final Log logger = LogFactory.getLog(PdmReader.class);
	private final String a = "attribute", c = "collection", o = "object";

	private final String cClasses = "c:Classes";
	private final String oClass = "o:Class";

	private final String cAttributes = "c:Attributes";
	private final String oAttribute = "o:Attribute";

	private final String cTables = "c:Tables";
	private final String oTable = "o:Table";

	private final String cColumns = "c:Columns";
	private final String oColumn = "o:Column";
	
	private final String aCode="a:Code";
	private final String aComment="a:Comment";
	
	private final String aMandatory="a:Mandatory";
	private final String aLength="a:Length";
	
	private String filePath;

	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	
	public PdmReader(){
		
	}
	
	public PdmReader(String filePath){
		this.filePath=filePath;
	}
	
	/**
	 * 从指定pdm文件中加载表信息
	 * @param filePath pdm文件路径
	 * @return
	 */
	public List<TableInfo> geTableInfos(String filePath) {
		this.filePath=filePath;
		return geTableInfos();
	}
	
	/**
	 * 从pdm文件中加载表信息
	 * @return
	 */
	public List<TableInfo> geTableInfos(){
		List<TableInfo> tableInfos=new ArrayList<TableInfo>();
		SAXReader reader=new SAXReader();
		Document document=null;
		try {
			document=reader.read(new File(filePath));
		} catch (NullPointerException nullPointerException) {
			logger.error("找不到文件。"+nullPointerException.getMessage());
			return null;
		}
		catch (DocumentException documentException) {
			logger.error("解析文件出错。"+documentException.getMessage());
			return null;
		}
		//获取<o:Table>节点列表，<o:Table>节点包含数据库中表及其所含字段信息
		List<Element> elements=document.selectNodes("//"+cTables+"/"+oTable);
		logger.info("Table count "+elements.size());
		TableInfo tableInfo=null;
		for (Element element : elements) {
			tableInfo=parseTableinfo(element);
			if (tableInfo!=null) {
				tableInfos.add(tableInfo);
			}
			//logger.info(element.attribute("a:Name"));
		}
		
		return tableInfos;
	}
	
	/**
	 * 将<o:Table></o:Table>节点中的信息解析出来
	 * @param element 包含<o:Table></o:Table>元素的XML段
	 * @return 解析成<see>Tableinfo</see>表示的数据表
	 */
	private TableInfo parseTableinfo(Element element){
		TableInfo tableInfo=null;
		ColumnInfo columnInfo=null;
		if (element!=null) {
			tableInfo=new TableInfo();
			tableInfo.setTableName(element.element(aCode).getTextTrim());
			tableInfo.setRemarks(element.element(aComment).getTextTrim());
			List<Element> childElements=element.element(cColumns).elements(oColumn);
			//TODO 需要完善
			for (Element childElement : childElements) {
				columnInfo=new ColumnInfo();
				/*if(childElement.getName().equals("a:Name")){
					
				}else if (childElement.getName().equals("a:Code")) {
					
				}*/
				columnInfo.setColumnName(childElement.elementTextTrim(aCode));
				columnInfo.setRemarks(childElement.elementTextTrim(aComment));
				int mandatory=0;
				if(childElement.elementTextTrim(aMandatory)!=null){
					mandatory=Integer.parseInt(childElement.elementTextTrim(aMandatory));
				}
				if(mandatory==1){
					columnInfo.setNullable(false);
				}else {
					columnInfo.setNullable(true);
				}
				columnInfo.setMaxLength(Integer.parseInt(childElement.elementTextTrim(aLength)));
				//columnInfo.setNullable(nullable);
			}
		}
		return tableInfo;
	}
	
	
	/*private void listElement(Element rootElement){
		for (Iterator iterator = rootElement.elementIterator(); iterator.hasNext();) {
			Element element=(Element) iterator.next();
			logger.info("UniquePath="+element.getUniquePath()+",QualifiedName="+element.getQualifiedName());
			listElement(element);
		}
	}*/
}
